﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;
using System.Net;
using System.Net.Http.Json;
using System.Collections.Concurrent;

namespace _02_Configuration.Extensions.Ison
{
    public class IsonConfigurationProvider : IConfigurationProvider
    {
        private ConcurrentDictionary<string, string> values = new ConcurrentDictionary<string, string>();
        private IsonConfigurationSource options;
        private CancellationTokenSource? tokenSource;
        public IsonConfigurationProvider(IsonConfigurationSource options)
        {
            this.options = options;
            //如果需要监听
            if (this.options.ReloadOnChange)
            {
                Watch();
            }
        }
        private void Watch()
        {
            //注册事件
            ChangeToken.OnChange(GetReloadToken, () =>
            {
                Load();

            });
            //模拟更改
            var t = new Thread(() =>
            {

                while (true)
                {
                    var token = tokenSource;
                    tokenSource = null;
                    //每3s之后发生更改
                    Thread.Sleep(3000);
                    //触发事件,触发之前一定要将tokenSource设置成null
                    token!.Cancel();
                }
            });
            t.Start();
        }
        public IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys, string parentPath)
        {
            return values.Keys;
        }

        public IChangeToken GetReloadToken()
        {
            lock (this)
            {
                if (tokenSource == null)
                {
                    tokenSource = new CancellationTokenSource();
                }
                return new CancellationChangeToken(tokenSource!.Token);
            }
        }

        public void Load()
        {
            //假设我们从第三方地址获取
            //var client = new HttpClient();
            //var response = client.GetAsync(source.Url).GetAwaiter().GetResult();
            //var json = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
            values.TryAdd("t1", "1111111");
            values.TryAdd("t2", DateTime.Now.ToString("HH-mm-ss"));
            Console.WriteLine("ison文件已加载...");
        }

        public void Set(string key, string value)
        {
            values.TryAdd(key, value);
        }

        public bool TryGet(string key, out string value)
        {
            var flag = values.TryGetValue(key, out string? data);
            value = data ?? string.Empty;
            return flag;
        }
    }
}